﻿/**
 * The IVIEW interface defines the features that a view should offer to integrate
 * with the system. Thus it defines methods for some publish-subscribe functionality towards
 * different user interface controls eg. play, pause button-click events.
 * CA is used as short for cellular automa(a|ton)
 * Author: Anderes Høst | ahkj@itu.dk
 * Date: 04 Dec 2010
 */
using System;
using System.Collections.Generic;
using AutomaTones.Model.Automaton_Model;
using AutomaTones.Model.Automaton_Model.RuleLib;
using AutomaTones.Model.MIDI.Mappers;
using AutomaTones.Model.Tools;
using Midi;

namespace AutomaTones.View {
    public interface IView
    {
        /// <summary>
        /// Method that will be notified when the Controller wants the IView to change state of the xPos, yPos
        /// that is passed in. 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="state"></param>
        void SetCell(int x, int y, State state);

        /// <summary>
        /// Method that will be notified whe nthe Controller wants the IVies to display a whole
        /// grid of CA.
        /// </summary>
        /// <param name="grid"></param>
         void SetGrid(State[,] grid);

        /// <summary>
        /// Method to send handy information on what it expects will
        /// happen next, help messages and the like. Implementers of the IVIEW 
        /// should be able to easily forward these messages to end users.
        /// </summary>
        /// <param name="message"></param>
        void SystemMessage(String message);

        /// <summary>
        /// Method to tell to view what Midi Channel that are available
        /// </summary>
        void DisplayChannels(List<Channel> channel);
        
        /// <summary>
        /// Reset the grid. that is, size it to its standard dimension.
        /// </summary>
        void ResetGrid();

        /// <summary>
        /// Method that sets the dimesion of a grid that can display CA. 
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="rows"></param>
        void SetGridDimension(int columns = 8, int rows = 8);

        /// <summary>
        /// Defines the CA rules available in the system.
        /// </summary>
        void DisplayCATypes(List<CAType> caTypes);

        /// <summary>
        /// Defines the Input modes available in the system.
        /// </summary>
        /// <param name="list"></param>
        void DisplayInputModes(List<InputMode> list);

        /// <summary>
        /// Defines the Mappers available in the system
        /// </summary>
        /// <param name="list"></param>
        void DisplayMappers(List<Mapper> list);

        /// <summary>
        /// CA patterns that are know by the system as preconfigurations
        /// </summary>
        List<GameOfLife.GofPattern> Patterns { get; set; }

        /// <summary>
        /// Patterns than can be dropped off onto a cell
        /// </summary>
        Action<GameOfLife.GofPattern, int, int> OnApplyCaPatternEvent { get; set; }

        /// <summary>
        /// The notion of an 'Ok' button. Controllers will subscribe to this for confirmation on user input. Eg. setting up
        /// a cellular preset the user presses 'ok', the user enters a rule and presse 'ok'. The latter will be called 
        /// indi_rectily if the user presses 'Play' 
        /// </summary>
        Action OnOkButtonClickEvent { get; set; }

        /// <summary>
        /// The notion of a 'Play' button. Will make the system intend to create and output music corresponding
        /// to the intention of the view.
        /// </summary>
        Action OnPlayButtonClickEvent { get; set; }

        /// <summary>
        /// The notion of a 'Rewind' button. Will make the the current CA music go back in time
        /// incrementially.
        /// </summary>
        Action OnRewindButtonClickEvent { get; set; }

        /// <summary>
        /// The notion of a 'FastForward' button. Will make the the current CA music go forward in time
        /// incrementially.
        /// </summary>
        Action OnForwardButtonClickEvent { get; set; }

        /// <summary>
        /// The notion of a 'Pause' button. Will make the system pause the CA relevant to this view.
        /// </summary>
        Action OnPauseButtonClickEvent { get; set; }

        /// <summary>
        /// Events for when a users of the system intents to interact with a CA placed in the grid.
        /// </summary>
        Action<int, int> OnCellClickEvent { get; set; }

        /// <summary>
        /// Method that should be called when the user of the system changes a volume control. Interger <i>i</i> should be in the
        /// range 0 < i < 100
        /// </summary>
        Action<int> OnVolumeChangeEvent { get; set; }

        /// <summary>
        /// Delegate to be used for changing channel. Controller will change the midi sound. 
        /// </summary>
        Action<Channel> OnChannelChangeEvent { get; set; }

        /// <summary>
        /// delegate to be be used when the user of the system 
        /// selects a new instrument from the list of instruments. Available instruments are offered
        /// by the controller through the instruments property.
        /// </summary>
        Action<InputMode> OnInputModeChangeEvent { get; set; }

        /// <summary>
        /// Called when the user selects a new typ of CA behaviour eg. an 'AutomaDrum', 'AutomaSong' or 
        /// the like. To obtain a list of the different input modes use the InputModes property
        /// </summary>
        Action<CAType> OnCATypeChangeEvent { get; set; }

        /// <summary>
        /// Called when the user selects a new typ of mapper eg. an 'AutomaDrum', 'AutomaSong' or 
        /// the like. To obtain a list of the different input modes use the InputModes property
        /// </summary>
        Action<Mapper> OnMapperChangeEvent { get; set; }

        /// <summary>
        /// Delegate for when a user of the system user wants to save the current CA. Simple send a 
        /// name for the CA
        /// </summary>
        Action<String> OnSaveButtonClickEvent { get; set; }

        /// <summary>
        /// delegate loading a CA. It's to be invoke with the full path of the .ser file to be loaded.
        /// </summary>
        Action<String> OnLoadButtonClickEvent { get; set; }

        /// <summary>
        /// Display the volume equalivant to the one that is in output
        /// </summary>
        /// <param name="Volume"></param>
        void SetVolume(int volume);

        /// <summary>
        /// The size of a custom grid, possibly changing, size of a 
        /// grid defined by the implementer of the interface.
        /// </summary>
        State[,] CustomGrid { get; set; }

        /// <summary>
        /// Called when the controller wants the view to display a certian
        /// channel as displayed.
        /// </summary>
        /// <param name="channel"></param>
        void DisplayChannel(Channel channel);
    }
}
